﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Diagnostics;
using GUILib;
using SQLLib;
using System.Windows.Input;
//using SQLiteDatabaseUtility.Model;

namespace SQLiteDatabaseUtility.ViewModel
{
    class MainViewModel : ViewModelBase
    {
        #region Data and Properties
        private readonly ObservableCollection<string> _output;
        public ObservableCollection<string> Output
        {
            get
            {
                return _output;
            }
        }

        private readonly ObservableCollection<string> _previousCommands;
        public ObservableCollection<string> PreviousCommands
        {
            get
            {
                return _previousCommands;
            }
        }

        private int CommandNumber = -1;

        private string _command;
        public string Command
        {
            get
            {
                return _command;
            }
            set
            {
                _command = value;
                NotifyPropertyChanged("Command");
                NotifyPropertyChanged("CanExecuteCommand");
            }
        }

        private SQLiteExecutor Executor;

        #endregion //Data and Properties

        #region Constructors
        public MainViewModel()
        {
            Executor = new SQLiteExecutor();
            Command = "";
            CommandNumber = -1;
            _output = new ObservableCollection<string>();
            _previousCommands = new ObservableCollection<string>();
            Output.Add("Type !Help or Help to view avaliable commands.");

        }
        #endregion //Constructors

        #region Methods
        #endregion //Methods

        #region Commands and Command Methods

        public ICommand ExecuteCommandCommand
        {
            get
            {
                return Commands.GetOrCreateCommand(
                    () => this.ExecuteCommandCommand,
                    (parameter) => DoExecuteCommand(parameter),
                    CanExecuteCommand);
            }
        }

        private void DoExecuteCommand(object parameter)
        {
            bool error;
            PreviousCommands.Add(Command);
            Output.Add("\nExecuting Command: " + Command);
            
            Output.Add(Executor.ExecuteCommand(Command, out error));
            CommandNumber = -1;
            Command = "";
        }
        private bool CanExecuteCommand()
        {
            if (Command.Length == 0)
            {
                return false;
            }
            return true;
        }

        public ICommand HistoryUpCommand
        {
            get
            {
                return Commands.GetOrCreateCommand(
                    () => this.HistoryUpCommand,
                    (parameter) => DoHistoryUpCommand(parameter) ,
                    () => true );
            }
        }
        private void DoHistoryUpCommand(object parameter)
        {
            CommandNumber++;
            TransverseHistory();
        }

        
        public ICommand HistoryDownCommand
        {
            get
            {
                return Commands.GetOrCreateCommand(
                    () => this.HistoryDownCommand,
                    (parameter) => DoHistoryDownCommand(parameter) ,
                    () => true);
            }
        }
        private void DoHistoryDownCommand(object parameter)
        {
            CommandNumber--;
            TransverseHistory();
        }

        private void TransverseHistory()
        {
            if (CommandNumber < 0)
            {
                CommandNumber = -1;
                Command = "";
                return;
            }
            else if (PreviousCommands.Count - CommandNumber <= 0)
            {
                CommandNumber = PreviousCommands.Count -1;
                Command = PreviousCommands[PreviousCommands.Count -1 - CommandNumber];
                return;
            }
            else
            {
                Command = PreviousCommands[PreviousCommands.Count -1 - CommandNumber];
            }
        }

        #endregion //Commands and Command Methods
    }
}
